using System.Text;
using System.Security.Cryptography;

namespace Ctyun.CF.SDK.Core;
public class CTSigner
{
    public static string GetEopAuthorization(string eopDate, string ak, string sk, string requestId, string sortQuery, string body)
    {
        if (string.IsNullOrEmpty(eopDate))
        {
            throw new ArgumentException("eopDate can not be empty");
        }
        if (string.IsNullOrEmpty(ak))
        {
            throw new ArgumentException("ak can not be empty");
        }
        if (string.IsNullOrEmpty(sk))
        {
            throw new ArgumentException("sk can not be empty");
        }
        if (string.IsNullOrEmpty(requestId))
        {
            throw new ArgumentException("requestId can not be empty");
        }
        if (string.IsNullOrEmpty(sortQuery))
        {
            sortQuery = "";
        }
        if (string.IsNullOrEmpty(body))
        {
            body = "";
        }
        var calculateContentHash = SHA256Hex(body);
        var singerDd = eopDate.Split('T')[0];
        var encHeader = string.Format("ctyun-eop-request-id:{0}\neop-date:{1}\n", requestId, eopDate);
        var sigture = encHeader + "\n" + sortQuery + "\n" + calculateContentHash;
        var ktime = HmacSHA256(Encoding.UTF8.GetBytes(eopDate), Encoding.UTF8.GetBytes(sk));
        var kak = HmacSHA256(Encoding.UTF8.GetBytes(ak), ktime);
        var kdate = HmacSHA256(Encoding.UTF8.GetBytes(singerDd), kak);
        var sw = HmacSHA256(Encoding.UTF8.GetBytes(sigture), kdate);
        var signature = Convert.ToBase64String(sw);
        var eopAuthorization = string.Format("{0} Headers=ctyun-eop-request-id;eop-date Signature={1}", ak, signature);
        return eopAuthorization;
    }

    static string SHA256Hex(string input)
    {
        byte[] inputBytes = Encoding.UTF8.GetBytes(input);
        using (SHA256 sha256 = SHA256.Create())
        {
            byte[] hashBytes = sha256.ComputeHash(inputBytes);
            StringBuilder sb = new StringBuilder();
            foreach (byte b in hashBytes)
            {
                sb.Append(b.ToString("x2"));
            }
            return sb.ToString();
        }
    }

    static byte[] HmacSHA256(byte[] data, byte[] key)
    {
        using (HMACSHA256 hmac = new HMACSHA256(key))
        {
            return hmac.ComputeHash(data);
        }
    }
}